#define DEF_MEASURE_DATAPARSE_H
#include "measure_dataParse.h"
#include "measure_p.h"

/******************************************************************
 * 函数名:measureDataParse()
 * 功能描述: 解析数据协议
 *          
 * 输入:data通信接口读到数据地址，size数据长度
 * 输出:
 * 返回值:true 解析正确，false解析出错
 *
 * 修改历史:
 * --------------------
 * 
 * --------------------
 *****************************************************************/
BOOL measureDataParse(U8* data, U32 size, MeasureParam *measParam) {
    protocolData.start = getU32Data(data, OFFSET_START);
    if (protocolData.start != START_VALUE) {
        return FALSE;
    }

    protocolData.check = getU32Data(data, OFFSET_CHECK);
    if (protocolData.check != CHECK_VALUE) {
        return FALSE;
    }

    protocolData.dynamicCheck = getU16Data(data, OFFSET_DYNAMIC_CHECK);
    protocolData.infoSize = getU16Data(data, OFFSET_INFO_SIZE);
    protocolData.runStatus = getU16Data(data, OFFSET_RUN_STATUS);
    protocolData.adcPrecision = getU16Data(data, OFFSET_ADC_PRECISION);
    protocolData.chNums = getU16Data(data, OFFSET_CH_NUMS);
    protocolData.waveDataSize = getU32Data(data, OFFSET_WAVE_DATA_SIZE);
    protocolData.frameNums = getU16Data(data, OFFSET_FRAME_NUMS);
    protocolData.fftValid = getU16Data(data, OFFSET_FFT_VALID);
    protocolData.fftDataSize = getU32Data(data, OFFSET_FFT_SIZE);
    protocolData.drawMode = getU16Data(data, OFFSET_DRAW_MODE);
    protocolData.rollMode = getU16Data(data, OFFSET_ROLL_MODE);
    protocolData.rollDataSize = getU32Data(data, OFFSET_ROLL_DATA_SIZE);


    protocolData.voltScale[CH1] = getU16Data(data, OFFSET_VOLTSCALE_CH1);
    protocolData.voltScale[CH2] = getU16Data(data, OFFSET_VOLTSCALE_CH2);
    protocolData.voltScale[CH3] = getU16Data(data, OFFSET_VOLTSCALE_CH3);
    protocolData.voltScale[CH4] = getU16Data(data, OFFSET_VOLTSCALE_CH4);

    protocolData.zero[CH1] = getF32Data(data, OFFSET_ZERO_CH1) * ADC_RATIO;
    protocolData.zero[CH2] = getF32Data(data, OFFSET_ZERO_CH2) * ADC_RATIO;
    protocolData.zero[CH3] = getF32Data(data, OFFSET_ZERO_CH3) * ADC_RATIO;
    protocolData.zero[CH4] = getF32Data(data, OFFSET_ZERO_CH4) * ADC_RATIO;

    protocolData.freq[CH1] = getU32Data(data, OFFSET_FREQ_CH1);
    protocolData.freq[CH2] = getU32Data(data, OFFSET_FREQ_CH2);
    protocolData.freq[CH3] = getU32Data(data, OFFSET_FREQ_CH3);
    protocolData.freq[CH4] = getU32Data(data, OFFSET_FREQ_CH4);
    protocolData.ref_freq[CH1] = getU32Data(data, OFFSET_REF_FREQ_CH1);
    protocolData.ref_freq[CH2] = getU32Data(data, OFFSET_REF_FREQ_CH2);
    protocolData.ref_freq[CH3] = getU32Data(data, OFFSET_REF_FREQ_CH3);
    protocolData.ref_freq[CH4] = getU32Data(data, OFFSET_REF_FREQ_CH4);

    protocolData.timePerData = getF32Data(data, OFFSET_TIMEPERDATA);

    protocolData.adcOverFlag = getU16Data(data, OFFSET_ADC_OVER_FLAG);
    protocolData.trigType = getU16Data(data, OFFSET_TRIG_TYPE);

    if (CHECKEMPTY_VALUE == protocolData.chNums) {
        return FALSE;
    }

    protocolData.dynamicCheckEnd = getU32Data(data, getDynamicCheckEndOffset());
    if (protocolData.dynamicCheckEnd != protocolData.dynamicCheck) {
        return FALSE;
    }

    protocolData.checkEnd = getU32Data(data, getCheckEndOffset());
    if (protocolData.checkEnd != CHECKEND_VALUE) {
        return FALSE;
    }
    protocolData.startEnd = getU32Data(data, getStartEndOffset());
    if (protocolData.startEnd != STARTEND_VALUE) {
        return FALSE;
    }

    measureDataDetach(data, size, measParam);

    return TRUE;
}

void measureDataDetach(U8* data, U32 size, MeasureParam *measParam) {

    int waveStart = protocolData.infoSize + 12;
    int cycleNum = protocolData.chNums; //只取第一帧数据,protocolData.chNums=1
    int offset_ch;
    int m;
    int k = protocolData.waveDataSize * 2 + 2;

    int ch;
    for (ch = CH1; ch < CH_TOTAL; ch++) {
        measParam->measItem[ch].voltScale = protocolData.voltScale[ch];
        measParam->measItem[ch].zero = protocolData.zero[ch];
        measParam->measItem[ch].onoff = OFF;
        measParam->measItem[ch].timePerData = protocolData.timePerData;
        measParam->measItem[ch].stepValue = getStepValue(protocolData.drawMode);
    }

    for (m = 0; m < cycleNum; m++) {
        offset_ch = waveStart + k*m;
        measureDataOneChannel(data + offset_ch, k, measParam);
    }
}

void measureDataOneChannel(U8* data, U32 size, MeasureParam *measParam) {
    int ch = getU16Data(data, 0);
    if (ch > CH_TOTAL) {
        return;
    }

    S16 *waveData = (S16*) (data + 2);
    S32 waveSize = (size - 2) / sizeof (U16);

    S32 sum, max, min;
    S32 i;
    S32 average;
    S32 zero;
    S32 maxPos = 0, minPos = 0;
    if (waveSize > ADC_SIZE) {
        return;
    }

    zero = measParam->measItem[ch].zero;

    sum = 0;
    max = min = waveData[0];
    for (i = 0; i < waveSize; i++) {
        if (max < waveData[i]) {
            max = waveData[i];
            maxPos = i;
        }
        if (min > waveData[i]) {
            min = waveData[i];
            minPos = i;
        }
        sum += waveData[i];
        measParam->measItem[ch].adc_without_zero[i] = (S32) waveData[i] - zero; //从数据包中分离每个通道ADC数据
    }

    if (max >= ADC_RATIO * 5 || min < (-ADC_RATIO * 5)) {
        measParam->measItem[ch].overflow = TRUE;
    } else {
        measParam->measItem[ch].overflow = FALSE;
    }

    average = sum / waveSize;
    average = average - zero;
    max = max - zero;
    min = min - zero;

    measParam->measItem[ch].waveSize = waveSize;
    measParam->measItem[ch].average = average;
    measParam->measItem[ch].max = max;
    measParam->measItem[ch].min = min;
    measParam->measItem[ch].pk_pk = max - min;
    measParam->measItem[ch].mindata_position = minPos;
    measParam->measItem[ch].maxdata_position = maxPos;
    measParam->measItem[ch].onoff = ON;
}

S32 getStepValue(S32 drawMode) {
    S32 step;
    switch (drawMode) {
        case 0:
            step = 1;
            break;
        case 1:
            step = 4;
            break;
        case 2:
            step = 1;
            break;
        case 3:
            step = 2;
            break;
        case 4:
            step = 2;
            break;
        default:
            step = 1;
            break;
    }
    return step;
}

S32 getDynamicCheckEndOffset() {
    S32 offset;
    S32 N1 = protocolData.infoSize;
    S32 N2 = protocolData.frameNums * protocolData.chNums * (protocolData.waveDataSize * 2 + 2);
    S32 N3 = protocolData.fftValid * (protocolData.fftDataSize * 2 + 2);

    offset = N1 + N2 + N3 + 16;

    return offset;
}

S32 getCheckEndOffset() {
    S32 offset;

    S32 dynamicCheckEnd = getDynamicCheckEndOffset();

    offset = dynamicCheckEnd + 2;

    return offset;
}

S32 getStartEndOffset() {
    S32 offset;

    S32 dynamicCheckEnd = getDynamicCheckEndOffset();

    offset = dynamicCheckEnd + 6;

    return offset;
}

U32 getU32Data(U8 *data, S32 offset) {
    U32 value;
    U8 *p = (U8*) & value;

    *p++ = data[offset++];
    *p++ = data[offset++];
    *p++ = data[offset++];
    *p++ = data[offset++];

    return value;
}

U16 getU16Data(U8 *data, S32 offset) {
    U16 value;
    U8 *p = (U8*) & value;

    *p++ = data[offset++];
    *p++ = data[offset++];

    return value;
}

F32 getF32Data(U8 *data, S32 offset) {
    F32 value;
    U8 *p = (U8*) & value;

    *p++ = data[offset++];
    *p++ = data[offset++];
    *p++ = data[offset++];
    *p++ = data[offset++];

    return value;
}
